import axios from 'axios';
import { ElNotification, ElMessageBox } from 'element-plus';
import sysConfig from "@/config";
import tool from '@/utils/tool';
import router from '@/router';

axios.defaults.baseURL = ''

axios.defaults.timeout = sysConfig.TIMEOUT

// HTTP request 拦截器
axios.interceptors.request.use(

	(config) => {
		let token = tool.data.get("TOKEN");
		if (token) {
			config.headers[sysConfig.TOKEN_NAME] = sysConfig.TOKEN_PREFIX + token;
		}
		if (!sysConfig.REQUEST_CACHE && config.method == 'get') {
			config.params = config.params || {};
			config.params['_'] = new Date().getTime();
		}
		Object.assign(config.headers, sysConfig.HEADERS)
		return config;
	},
	(error) => {
		return Promise.reject(error);
	}
);


// HTTP response 拦截器
axios.interceptors.response.use(
	(response) => {


		if (response.data.code == 404) {
			ElNotification.error({
				title: '请求错误',
				message: "Status:404，正在请求不存在的服务器记录！"
			});
		} else if (response.code == 500 || response.data.code == 500) {
			ElNotification.error({
				title: '请求错误',
				message: response.data.message || "Status:500，服务器发生错误！"
			});

		} else if (response.code == 401 || response.data.code == 401) {
			ElMessageBox.confirm('当前用户已被登出或无权限访问当前资源，请尝试重新登录后再操作。', '无权限访问', {
				type: 'error',
				closeOnClickModal: false,
				center: true,
				confirmButtonText: '重新登录'
			}).then(() => {
				router.replace({ path: '/login' });
			}).catch(() => { })
		}
		else if (response.code == 403 || response.data.code == 403) {

			ElNotification.error('当前用户已被登出或无权限访问当前资源，请申请权限。', '无权限访问', {
				title: '请求错误',
				message: response.data.message || "Status:403，无权限访问！"
			})
		}
		else {
			return response;
		}
		return Promise.resolve(response);
	},
	(error) => {
		if (error.response) {
			if (error.response.status == 404) {
				ElNotification.error({
					title: '请求错误',
					message: "Status:404，正在请求不存在的服务器记录！"
				});
			} else if (error.response.status == 500) {
				ElNotification.error({
					title: '请求错误',
					message: error.response.data.message || "Status:500，服务器发生错误！"
				});
			} else if (error.response.status == 401) {
				ElMessageBox.confirm('当前用户已被登出或无权限访问当前资源，请尝试重新登录后再操作。', '无权限访问', {
					type: 'error',
					closeOnClickModal: false,
					center: true,
					confirmButtonText: '重新登录'
				}).then(() => {
					router.replace({ path: '/login' });
				}).catch(() => { })
			} else {
				ElNotification.error({
					title: '请求错误',
					message: error.message || `Status:${error.response.status}，未知错误！`
				});
			}
		} else {
			if ((error.code ?? "") != 'ERR_CANCELED')
				ElNotification.error({
					title: '请求错误',
					message: "请求服务器无响应！"
				});
		}

		return Promise.resolve(error.response);
	}
);

var getStorageKey = (url, params) => url + "?" + Object.keys(params).map(key => key + '=' + JSON.stringify(params[key])).join('&');


var processRequestQueue = {};

export const http = {
	/** get 请求
	 * @param  {string} url 接口地址
	 * @param  {object} params 请求参数
	 * @param  {object} config 参数
	 */
	get: function (url, params = {}, config = {}) {
		var key = getStorageKey(url, params);
		if (processRequestQueue[key] == null || typeof processRequestQueue[key] == 'undefined') {
			processRequestQueue[key] = new Promise((resolve, reject) => {
				let data = tool.data.get(key);
				return config.cache && data ? resolve(data) :
					axios({
						method: 'get',
						url: url,
						params: params,
						...config
					}).then((response) => {
						response && config.cache && tool.data.set(key, response.data, 0);
						resolve(response?.data ?? response);

					}).catch((error) => {
						reject(error);
					}).finally(() => {
						delete processRequestQueue[key];
					})
			});
		}
		return processRequestQueue[key];
	},

	/** post 请求
	 * @param  {string} url 接口地址
	 * @param  {object} data 请求参数
	 * @param  {object} config 参数
	 */
	post: function (url, data = {}, config = {}) {
		return new Promise((resolve, reject) => {
			axios({
				method: 'post',
				url: url,
				data: data,
				...config
			}).then((response) => {
				resolve(response.data);
			}).catch((error) => {
				reject(error);
			})
		})
	},

	/** put 请求
	 * @param  {string} url 接口地址
	 * @param  {object} data 请求参数
	 * @param  {object} config 参数
	 */
	put: function (url, data = {}, config = {}) {
		return new Promise((resolve, reject) => {
			axios({
				method: 'put',
				url: url,
				data: data,
				...config
			}).then((response) => {
				resolve(response.data);
			}).catch((error) => {
				reject(error);
			})
		})
	},

	/** patch 请求
	 * @param  {string} url 接口地址
	 * @param  {object} data 请求参数
	 * @param  {object} config 参数
	 */
	patch: function (url, data = {}, config = {}) {
		return new Promise((resolve, reject) => {
			axios({
				method: 'patch',
				url: url,
				data: data,
				...config
			}).then((response) => {
				resolve(response.data);
			}).catch((error) => {
				reject(error);
			})
		})
	},

	/** delete 请求
	 * @param  {string} url 接口地址
	 * @param  {object} data 请求参数
	 * @param  {object} config 参数
	 */
	delete: function (url, data = {}, config = {}) {
		return new Promise((resolve, reject) => {
			axios({
				method: 'delete',
				url: url,
				data: data,
				...config
			}).then((response) => {
				resolve(response.data);
			}).catch((error) => {
				reject(error);
			})
		})
	},

	/** jsonp 请求
	 * @param  {string} url 接口地址
	 * @param  {string} name JSONP回调函数名称
	 */
	jsonp: function (url, name = 'jsonp') {
		return new Promise((resolve) => {
			var script = document.createElement('script')
			var _id = `jsonp${Math.ceil(Math.random() * 1000000)}`
			script.id = _id
			script.type = 'text/javascript'
			script.src = url
			window[name] = (response) => {
				resolve(response)
				document.getElementsByTagName('head')[0].removeChild(script)
				try {
					delete window[name];
				} catch (e) {
					window[name] = undefined;
				}
			}
			document.getElementsByTagName('head')[0].appendChild(script)
		})
	}
}

export class visitWeb {
	Attributes = {
		url: "",
		name: "",
		customerGet: null,
		customerPost: null,
		config: {},
		params: {}
	};
	get url() {
		return this.Attributes.url
	}
	//筛选
	filter = [];
	constructor(Attributes) {
		this.Attributes = Object.assign(this.Attributes, Attributes);
	}
	get = async (params = {}, config = {}) => {
		let res = null;
		if (this.Attributes.customerPost == null) {
			res = await http.get(this.Attributes.url, Object.assign({}, this.Attributes.params, this.setFilters(params)), Object.assign(this.Attributes.config, config));
		}
		else
			res = await this.Attributes.customerGet(Object.assign({}, this.Attributes.params, this.setFilters(params)), Object.assign(this.Attributes.config, config));
		return res;
	}
	destroycache = (params) => {
		var key = getStorageKey(this.Attributes.url, Object.assign({}, this.Attributes.params, this.setFilters(params)));
		tool.data.remove(key);
		return this;
	}

	post = async (params = {}, config = {}) => {
		let res = null;
		if (this.Attributes.customerPost == null) {
			res = await http.post(this.Attributes.url, Object.assign({}, this.Attributes.params, this.setFilters(params)), Object.assign(this.Attributes.config, config));
		}
		else
			res = await this.Attributes.customerPost(params, Object.assign(this.Attributes.config, config));
		return res;
	}
	setFilters(params) {

		if (typeof params.filter == "undefined" && this.filter.length > 0) {
			params['filter'] = [];
		}

		this.filter.filter((v) => {
			params['filter'].push(v);
		})
		return params;
	}
	reSetParam(params) {
		this.filter = [];
		params.filter((param) => this.setParam(param));
		return this;
	}
	setParam = (param) => {
		this.filter.push(param);
		return this;
	}
	setAttrib = ($attr) => {
		Object.assign(this.Attributes, $attr);
		return this;
	}

	//返回对象深拷贝
	cp(attr = {}) {
		return new visitWeb(Object.assign(this.Attributes, attr));
	}
}

